package com.oplink.webems.common.snmp.service;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import org.snmp4j.CommandResponder;
import org.snmp4j.CommandResponderEvent;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.MPv1;
import org.snmp4j.mp.MPv2c;
import org.snmp4j.mp.MPv3;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.DefaultUdpTransportMapping;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;
import org.springframework.stereotype.Component;

import com.oplink.webems.common.snmp.entity.TrapEvent;

@Component
public class TrapService implements CommandResponder, Runnable {
	private MultiThreadedMessageDispatcher dispatcher;  
    private Snmp snmp = null;  
    private Address listenAddress;  
    private ThreadPool threadPool; 
    
	@SuppressWarnings("rawtypes")
	private void init() throws UnknownHostException, IOException {  
        threadPool = ThreadPool.create("Trap", 2);  
        dispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());  
        listenAddress = GenericAddress.parse(System.getProperty("snmp4j.listenAddress", "udp:0.0.0.0/162")); // 本地IP与监听端口  
        TransportMapping transport;  
        // 对TCP与UDP协议进行处理  
        if (listenAddress instanceof UdpAddress) {  
            transport = new DefaultUdpTransportMapping((UdpAddress) listenAddress);  
        } else {  
            transport = new DefaultTcpTransportMapping((TcpAddress) listenAddress);  
        }  
        snmp = new Snmp(dispatcher, transport);  
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv1());  
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv2c());  
        snmp.getMessageDispatcher().addMessageProcessingModel(new MPv3());  
        USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);  
        SecurityModels.getInstance().addSecurityModel(usm);  
        snmp.listen();  
    }  
      
    public void run() {  
        try {  
            init();  
            snmp.addCommandResponder(this);  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
    }  
    
	@Override
	public void processPdu(CommandResponderEvent respEvnt) {
		//System.out.print(address.toString());
		if (respEvnt != null && respEvnt.getPDU() != null) {  
			Address address = respEvnt.getPeerAddress();
            @SuppressWarnings("unchecked")
			Vector<VariableBinding> recVBs = (Vector<VariableBinding>) (respEvnt.getPDU().getVariableBindings());
            //Vector<String> values = new Vector<String>();
            Map<String, String> trapmap = new HashMap<String, String>();
            //put ip 信息
            trapmap.put("ip", address.toString());
            for (int i = 0; i < recVBs.size(); i++) {  
                VariableBinding recVB = recVBs.elementAt(i);
                //values.add(recVB.getVariable().toString());
                trapmap.put(recVB.getOid().toString(), recVB.getVariable().toString());
            }  
            TrapEvent.getInstance().put(trapmap);
        }  		
	}
}
